/**
 * 动画系统核心模块
 * 处理动画逻辑、关键帧管理、时间轴控制等
 */

import { animationEngine } from '../engine'
import type { Keyframe, AnimationTrack } from '../engine'

// 动画状态枚举
export enum AnimationState {
  STOPPED = 'stopped',
  PLAYING = 'playing',
  PAUSED = 'paused'
}

// 播放配置接口
export interface PlaybackConfig {
  loop: boolean
  speed: number
  startTime: number
  endTime: number
}

// 动画控制器类
export class AnimationController {
  private state = AnimationState.STOPPED
  private currentTime = 0
  private totalDuration = 0
  private config: PlaybackConfig = {
    loop: false,
    speed: 1,
    startTime: 0,
    endTime: 0
  }
  private animationFrameId: number | null = null
  private lastFrameTime = 0
  private callbacks = {
    onTimeUpdate: [] as Array<(time: number) => void>,
    onStateChange: [] as Array<(state: AnimationState) => void>,
    onComplete: [] as Array<() => void>
  }

  constructor(duration = 5) {
    this.totalDuration = duration
    this.config.endTime = duration
  }

  // 播放动画
  play() {
    if (this.state === AnimationState.PLAYING) return
    
    this.state = AnimationState.PLAYING
    this.lastFrameTime = performance.now()
    this.startAnimationLoop()
    this.notifyStateChange()
  }

  // 暂停动画
  pause() {
    if (this.state !== AnimationState.PLAYING) return
    
    this.state = AnimationState.PAUSED
    this.stopAnimationLoop()
    this.notifyStateChange()
  }

  // 停止动画
  stop() {
    this.state = AnimationState.STOPPED
    this.currentTime = this.config.startTime
    this.stopAnimationLoop()
    this.notifyStateChange()
    this.notifyTimeUpdate()
  }

  // 跳转到指定时间
  seekTo(time: number) {
    this.currentTime = Math.max(this.config.startTime, Math.min(this.config.endTime, time))
    this.notifyTimeUpdate()
  }

  // 设置播放配置
  setConfig(config: Partial<PlaybackConfig>) {
    Object.assign(this.config, config)
    if (config.endTime !== undefined) {
      this.totalDuration = config.endTime
    }
  }

  // 获取当前状态
  getState() {
    return {
      state: this.state,
      currentTime: this.currentTime,
      totalDuration: this.totalDuration,
      config: { ...this.config }
    }
  }

  // 添加事件监听器
  on(event: 'timeUpdate', callback: (time: number) => void): void
  on(event: 'stateChange', callback: (state: AnimationState) => void): void
  on(event: 'complete', callback: () => void): void
  on(event: string, callback: any) {
    if (event in this.callbacks) {
      (this.callbacks as any)[event].push(callback)
    }
  }

  // 移除事件监听器
  off(event: string, callback: any) {
    if (event in this.callbacks) {
      const callbacks = (this.callbacks as any)[event]
      const index = callbacks.indexOf(callback)
      if (index > -1) {
        callbacks.splice(index, 1)
      }
    }
  }

  // 开始动画循环
  private startAnimationLoop() {
    const animate = (currentFrameTime: number) => {
      if (this.state !== AnimationState.PLAYING) return

      const deltaTime = (currentFrameTime - this.lastFrameTime) / 1000 * this.config.speed
      this.lastFrameTime = currentFrameTime

      this.currentTime += deltaTime

      // 检查是否到达结束时间
      if (this.currentTime >= this.config.endTime) {
        if (this.config.loop) {
          this.currentTime = this.config.startTime
        } else {
          this.currentTime = this.config.endTime
          this.stop()
          this.notifyComplete()
          return
        }
      }

      this.notifyTimeUpdate()
      this.animationFrameId = requestAnimationFrame(animate)
    }

    this.animationFrameId = requestAnimationFrame(animate)
  }

  // 停止动画循环
  private stopAnimationLoop() {
    if (this.animationFrameId) {
      cancelAnimationFrame(this.animationFrameId)
      this.animationFrameId = null
    }
  }

  // 通知时间更新
  private notifyTimeUpdate() {
    this.callbacks.onTimeUpdate.forEach(callback => callback(this.currentTime))
  }

  // 通知状态变化
  private notifyStateChange() {
    this.callbacks.onStateChange.forEach(callback => callback(this.state))
  }

  // 通知播放完成
  private notifyComplete() {
    this.callbacks.onComplete.forEach(callback => callback())
  }

  // 清理资源
  dispose() {
    this.stopAnimationLoop()
    this.callbacks.onTimeUpdate = []
    this.callbacks.onStateChange = []
    this.callbacks.onComplete = []
  }
}

// 关键帧管理器
export class KeyframeManager {
  // 添加关键帧
  static addKeyframe(track: AnimationTrack, keyframe: Keyframe): AnimationTrack {
    const newKeyframes = [...track.keyframes, keyframe]
      .sort((a, b) => a.time - b.time)
    
    return {
      ...track,
      keyframes: newKeyframes
    }
  }

  // 删除关键帧
  static removeKeyframe(track: AnimationTrack, time: number): AnimationTrack {
    const newKeyframes = track.keyframes.filter(kf => kf.time !== time)
    
    return {
      ...track,
      keyframes: newKeyframes
    }
  }

  // 更新关键帧
  static updateKeyframe(track: AnimationTrack, oldTime: number, newKeyframe: Keyframe): AnimationTrack {
    const newKeyframes = track.keyframes
      .filter(kf => kf.time !== oldTime)
      .concat(newKeyframe)
      .sort((a, b) => a.time - b.time)
    
    return {
      ...track,
      keyframes: newKeyframes
    }
  }

  // 获取指定时间的关键帧
  static getKeyframeAtTime(track: AnimationTrack, time: number): Keyframe | null {
    return track.keyframes.find(kf => kf.time === time) || null
  }

  // 获取时间范围内的关键帧
  static getKeyframesInRange(track: AnimationTrack, startTime: number, endTime: number): Keyframe[] {
    return track.keyframes.filter(kf => kf.time >= startTime && kf.time <= endTime)
  }

  // 优化轨道关键帧
  static optimizeTrack(track: AnimationTrack, tolerance = 0.001): AnimationTrack {
    return animationEngine.optimizeKeyframes(track, tolerance)
  }
}

// 时间轴工具函数
export class TimelineUtils {
  // 格式化时间显示
  static formatTime(seconds: number): string {
    const minutes = Math.floor(seconds / 60)
    const secs = Math.floor(seconds % 60)
    const ms = Math.floor((seconds % 1) * 100)
    
    return `${minutes}:${secs.toString().padStart(2, '0')}.${ms.toString().padStart(2, '0')}`
  }

  // 解析时间字符串
  static parseTime(timeString: string): number {
    const parts = timeString.split(':')
    if (parts.length !== 2) return 0
    
    const minutes = parseInt(parts[0]) || 0
    const secondsParts = parts[1].split('.')
    const seconds = parseInt(secondsParts[0]) || 0
    const ms = parseInt(secondsParts[1]) || 0
    
    return minutes * 60 + seconds + ms / 100
  }

  // 计算时间轴刻度
  static calculateTimeMarks(duration: number, zoom: number): Array<{ time: number; label: string; major: boolean }> {
    const marks: Array<{ time: number; label: string; major: boolean }> = []
    
    // 根据缩放级别确定刻度间隔
    let interval = 1 // 秒
    if (zoom < 10) interval = 5
    else if (zoom < 20) interval = 1
    else if (zoom < 50) interval = 0.5
    else interval = 0.1
    
    for (let time = 0; time <= duration; time += interval) {
      const major = time % 1 === 0 // 整秒为主刻度
      marks.push({
        time,
        label: major ? this.formatTime(time) : '',
        major
      })
    }
    
    return marks
  }

  // 吸附时间到网格
  static snapToGrid(time: number, gridSize = 0.1): number {
    return Math.round(time / gridSize) * gridSize
  }
}

// 导出默认动画控制器实例
export const defaultAnimationController = new AnimationController()
